
uniform sampler2D		bumpMap;
uniform sampler2D		diffuseMap;
uniform sampler2D		specularMap;
uniform sampler2D		lightProjectionMap;
uniform sampler2D		lightFalloffMap;

uniform vec3		diffuseColor;
uniform vec3		specularColor;
uniform float		specularExponent;
uniform float		specularBrightness;

varying vec3		viewVector;
varying vec3		lightVector;
varying vec2		bumpTexCoord;
varying vec2		diffuseTexCoord;
varying vec2		specularTexCoord;
varying vec4		lightTexCoord;
varying vec4		vertexColor;


void main (void){

	vec3		viewVec, lightVec, halfAngleVec, normalVec;
	vec3		diffuse, specular, intensity;

	// Normalize the view vector
	viewVec = normalize(viewVector);

	// Normalize the light vector
	lightVec = normalize(lightVector);

	// Load the normal vector from the bump map
	normalVec = texture2D(bumpMap, bumpTexCoord).rgb * 2.0 - 1.0;
	normalVec = normalize(normalVec);

	// Modulate the diffuse map by the diffuse color
	diffuse = texture2D(diffuseMap, diffuseTexCoord).rgb * diffuseColor;

	// Modulate the specular map by the specular color
	specular = texture2D(specularMap, specularTexCoord).rgb * specularColor;

	// Compute diffuse light contribution
	intensity = vec3(dot(lightVec, normalVec));

	// Modulate by the light projection and falloff
	intensity *= texture2DProj(lightProjectionMap, lightTexCoord.stq).rgb;
	intensity *= texture2D(lightFalloffMap, vec2(lightTexCoord.p, 0.5)).rgb;

	// Compute specular light contribution
	halfAngleVec = normalize(viewVec + lightVec);

	specular *= pow(max(dot(halfAngleVec, normalVec), 0.0), specularExponent) * specularBrightness;

	// Compute diffuse + specular color, apply light attenuation, and modulate by the vertex color
	gl_FragColor = vec4((diffuse + specular) * intensity, 1.0) * vertexColor;
}
